package uiLayer.uiUtilities;

import java.util.ArrayList;
import java.util.List;

import javax.swing.DefaultListSelectionModel;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumnModel;

public abstract class CustomTable <T> extends JTable {
	private CustomTableModel tableModel;

	public CustomTable() {
		tableModel = new CustomTableModel();
		this.setModel(tableModel);
		super.setSelectionMode(DefaultListSelectionModel.SINGLE_SELECTION);
		this.setFillsViewportHeight(false);
		this.setAutoCreateRowSorter(false);
		this.setRowHeight(22);
	}

	public final void loadTableData(List<T> objectList) {
		this.tableModel.setModel(objectList);
	}
	
	public final void fireTableDataChanged() {
		this.tableModel.fireTableDataChanged();
	}

	public final void setColNames(String... colNames) {
		this.tableModel.setColNames(colNames);
	}

	public final void rightRenderColumns(int... colNo) {
		TableColumnModel m = super.getColumnModel();
		DefaultTableCellRenderer renderRight = new DefaultTableCellRenderer();
		{
			renderRight.setHorizontalAlignment(SwingConstants.RIGHT);
			for(int no : colNo) {
				m.getColumn(no).setCellRenderer(renderRight);
			}
		}
	}
	
	public final void centerRenderColumns(int... colNo) {
		TableColumnModel m = super.getColumnModel();
		DefaultTableCellRenderer renderCenter = new DefaultTableCellRenderer();
		{
			renderCenter.setHorizontalAlignment(SwingConstants.CENTER);
			for(int no : colNo) {
				m.getColumn(no).setCellRenderer(renderCenter);
			}
		}
	}

	public final void setColumnWidth(int colNo, int minWidth, int maxWidth) {
		TableColumnModel m = super.getColumnModel();
		m.getColumn(colNo).setMinWidth(minWidth);
		m.getColumn(colNo).setMaxWidth(maxWidth);
	}

	public abstract Object getCellValue(int col, T o);

	public final T getSelectedObject() {
		int row = getSelectedRow();
		if (row < 0){
			return null;
		}
		return this.tableModel.getObjectByIndex(row);
	}


	private class CustomTableModel extends AbstractTableModel{
		private List<T> model = new ArrayList<>();
		private String[] colNames = {};

		public void setModel(List<T> model){
			this.model = model;
			super.fireTableDataChanged();
		}

		public void setColNames(String[] colNames){
			this.colNames = colNames;
			super.fireTableStructureChanged();
		}

		@Override
		public String getColumnName(int column) {
			return colNames[column];
		}

		@Override
		public int getColumnCount() {
			return colNames.length;
		}

		@Override
		public int getRowCount() {
			return model == null ? 0 : model.size();
		}

		@Override
		public Object getValueAt(int row, int col) {
			return getCellValue(col, model.get(row));
		}
		
		public T getObjectByIndex(int row) {
			return model.get(row);
		}

	}





}
